# -*- coding: UTF8 -*-
import random
import string

from xmpp import *
from Queue import *
import Behaviour
import ACLParser
import Envelope
import ACLMessage
import BasicFipaDateTime
import XMLCodec
import DF
import time
import AID

class CreationError(Exception):
       def __init__(self):
           Exception.__init__(self)
class NotValidName(CreationError):
    def __init__(self):
        CreationError.__init__(self)
class NotValidGoalChange(Exception):
    def __init__(self):
        Exception.__init__(self)
class NotValidType(CreationError):
    def __init__(self):
        CreationError.__init__(self)
class NotValidGoal(CreationError):
    def __init__(self):
        CreationError.__init__(self)
class NotCreatePermision(CreationError):
    def __init__(self):
        CreationError.__init__(self)
class NotSupervisor(CreationError):
    def __init__(self):
        CreationError.__init__(self)
class JoinError(Exception):
    def __init__(self):
        Exception.__init__(self)
class PaswordNeeded(JoinError):
    def __init__(self):
        JoinError.__init__(self)
class MembersOnly(JoinError):
     def __init__(self):
         JoinError.__init__(self)
class BanedUser(JoinError):
    def __init__(self):
        JoinError.__init__(self)
class NickNameConflict(JoinError):
    def __init__(self):
        JoinError.__init__(self)
class MaximumUsers(JoinError):
    def __init__(self):
        JoinError.__init__(self)
class LockedUnit(JoinError):
    def __init__(self):
        JoinError.__init__(self)
class DestroyError(Exception):
    def __init__(self):
        Exception.__init__(self)
class NotValidUnit(Exception):
    def __init__(self):
        Exception.__init__(self)
class LastOwner(Exception):
    def __init__(self):
        Exception.__init__(self)
class NotAllowed(Exception):
    def __init__(self):
        Exception.__init__(self)
class Unavailable(Exception):
    def __init__(self):
        Exception.__init__(self)
class PaswordNeeded(Exception):
    def __init__(self):
        Exception.__init__(self)

class Unit(Behaviour.Behaviour):

    def __init__(self, agent,nick, name, type="Team", goalList=[], agentList=[], contentLanguage="sl",password=None,create=True):
        Behaviour.Behaviour.__init__(self)
        self.myAgent=agent
        self.platform = self.myAgent.getSpadePlatformJID()
        self.muc_name = self.myAgent.getMUC()
        self.name = name
        self.type = type
        self.goalList = goalList
        self.agentList = agentList
        self.contentLanguage = contentLanguage
        self.nick=nick
        self.password=password
        self.create=create
        self.parent_type=None
        self.parent=None
        self.state="unavailable"
        self.UnavailableMsg="Unit"
        self.members=[]
        self.owner=False
        self.orgOwner=[]
        self.requestBehaviour=None


    def setup(self):
        pass




    def myJoin(self):
          #The Organization exists
          if not self.testUnitName():
              return NotValidName
            #The room no existe
          else:
              code=self.myJoinRoom()
              if code!=True:
                    if code=="401":
                        return PasswordNeeded
                    if code=="407":
                        return MembersOnly
                    if code=="403":
                        return BanedUser
                    if code=="409":
                        return NickNameConflict
                    if code=="503":
                        return MaximumUsers
                    if code=="404":
                        return LockedUnit
              else:
                  self.state="available"
                  info=self.getInfo()
                  if info:
                      self.type = info["type"]
                      self.contentLanguage = info["contentLanguage"]
                      self.parent=info["parent"]
                      parentName=self.parent.split(":")[0]
                      parent_info=self.myAgent.getOrganizationInfo(parentName)
                      #print parent_info
                      self.parent_type=parent_info["type"]
                      self.goal=info["goal"]
                  #añadiendo la plantilla de los mensajes que se pueden recibir
                  template = Behaviour.ACLTemplate()
                  template.setProperty("from",self.name)
                  t = Behaviour.MessageTemplate(template)
                  self.setTemplate(t)
                  #añadiendo la plantilla de los mensajes de presencia de la sala
                  p = Presence(frm=self.name+"@"+self.muc_name)
                  t = Behaviour.MessageTemplate(p)
                  self.presenceBehaviour=self.PresenceBehaviour(self.muc_name,self.name,self.nick,self)
                  self.myAgent.addBehaviour(self.presenceBehaviour, t)
                  return True




    def testRoomName(self):
        """checks if exists a room with the same name"""
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        iq = Iq(frm=self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(iq)
        b=self.TestRoomNameBehaviour(ID,self.muc_name,self.name)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result





    class TestRoomNameBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,ID,muc_name,roomname):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.result = False
            self.muc_name=muc_name
            self.roomname=roomname

        def _process(self):
           iq = Iq(to=self.muc_name,typ='get', attrs={"id":self.ID})
           query = Protocol('query',xmlns="http://jabber.org/protocol/disco#items")
           iq.addChild(node=query)
           self.myAgent.jabber.send(iq)
           msg = self._receive(True,10)
           if msg:
               if query:
                   self.result = True
                   items = msg.getQueryChildren()
                   for item in items:
                       if item.getAttr("jid") == str(self.roomname+"@"+self.muc_name):
                           self.result = False
               else:
                   self.result = False


    def createRoom(self):
        """creates a new room"""
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Presence(frm=self.name+"@"+self.muc_name+"/"+self.nick)
        t1 = Behaviour.MessageTemplate(p)
        b=self.CreateRoomBehaviour(ID,self.muc_name,self.name,self.nick,self.parent,self.contentLanguage,self.type,self.goalList,self.password,self.orgOwner)
        self.myAgent.addBehaviour(b, t1)
        b.join()
        return b.result

    class CreateRoomBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,ID,muc_name,roomname,nick,parent,contentLanguage,type,goalList,password,orgOwner):
            Behaviour.OneShotBehaviour.__init__(self)
            self.result = False
            self.ID=ID
            self.nick=nick
            self.muc_name=muc_name
            self.name=roomname
            self.parent=parent
            self.contentLanguage=contentLanguage
            self.type=type
            self.goalList=goalList
            self.password=password
            self.orgOwner=orgOwner

        def _process(self):
            p = Presence(to=self.name+"@"+self.muc_name+"/"+self.nick)
            x = Protocol("x", xmlns="http://jabber.org/protocol/muc")
            p.addChild(node=x)
            self.myAgent.jabber.send(p)
            msg=self._receive(True,10)
            if msg:
                if msg.getAttr("type")=="error":
                    print "Room creation is restricted"
                    self.result= False
                    return
            else:
                    self.result= False
                    return
            template= Iq(frm=self.name+"@"+self.muc_name, attrs={"id":self.ID})
            t = Behaviour.MessageTemplate(template)
            self.setTemplate(t)
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)

            msg = self._receive(True,10)
            #para descartar los presence anteriores
            while msg and msg.getName()!="iq":
                msg = self._receive(True,10)

            #setting room configuration
            if not msg or msg.getAttr("type")=="error":
                print "No configuration is possible: "+msg.getError()
                self.result= False
                return
            ispasswordprotected=False
            if self.type=="Hierarchy" or self.password!=None:
                ispasswordprotected=True
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
            x=Node(tag="x", attrs={"xmlns":"jabber:x:data"," type":"submit"})
            resquery=msg.getQueryChildren()[0] #nos quedamos con el hijo de query
            if resquery: items = resquery.getTags("field")
            if resquery==None:
                print "No configuration is possible"
                return False
            for item in items:
              if item.getAttr("var"):
                value=None
                if item.getAttr("var") == "muc#roomconfig_lang":
                  value=self.contentLanguage
                if item.getAttr("var") == "muc#roomconfig_roomdesc":
                  value=self.type
                if item.getAttr("var") == "muc#roomconfig_roomname":
                  value=self.name
                if item.getAttr("var") == "muc#roomconfig_roomtype":
                    value=self.parent+":"+self.name
                if item.getAttr("var") == "muc#roomconfig_presencebroadcast":
                    if self.type=="Hierarchy":
                        value="moderator"
                    else:
                        value="visitor"
                if item.getAttr("var") == "muc#roomconfig_persistentroom":
                  value="1"
                if item.getAttr("var") == "muc#roomconfig_publicroom":
                  value="1"
                if item.getAttr("var") == "muc#roomconfig_moderatedroom":
                     if self.type=="Flat":
                        value="0"
                     else:
                        value="1"
                if item.getAttr("var") == "muc#roomconfig_passwordprotectedroom":
                   if ispasswordprotected:
                        value="1"
                   else:
                       value="0"
                if item.getAttr("var")=="muc#roomconfig_roomsecret":
                    value=self.password
                if item.getAttr("var") == "muc#roomconfig_whois":
                    if self.type=="Hierarchy":
                        value="moderators"
                    else:
                        value="anyone"
                if item.getAttr("var") == "muc#roomconfig_changesubject":
                    if self.type=="Flat":
                        value="1"
                    else:
                        value="0"
                if item.getAttr("var") == "muc#roomconfig_allowinvites":
                    if self.type=="Hierarchy":
                        value="0"
                    else:
                        value="1"
                if item.getAttr("var") == "muc#roomconfig_membersonly":
                    if self.type=="Flat":
                        value="0"
                    else:
                        value="1"
                node=Node(tag="field", attrs={"var":item.getAttr("var")})
                valnode=Node(tag="value")
                valnode.addData(value)
                node.addChild(node=valnode)
                if(item.getAttr("var")!="muc#roomconfig_roomsecret" or ispasswordprotected) and value!=None:
                    x.addChild(node=node)
            query.addChild(node=x)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg and msg.getAttr("type")=="result":

              m = Message(to=self.name+"@"+self.muc_name, typ="groupchat")
              sub = Node(tag="subject")
              sub.addData(str(self.goalList))
              m.addChild(node=sub)
              self.myAgent.jabber.send(m)
              #añadiendo a los owners superiores
              for o in self.orgOwner:
                  self.myAgent.jabber.send(iq)
                  iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                  query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                  item= Node(tag="item", attrs={"affiliation":"owner","jid":o})
                  query.addChild(node=item)
                  iq.addChild(node=query)
                  self.myAgent.jabber.send(iq)
              if self.name not in self.myAgent.rooms:
                self.myAgent.rooms.append(self.name)
              self.result= True
              return
            else:
              self.result= False
              return

    def myJoinRoom(self):
        """agent joins the room"""
        p = Presence(frm=self.name+"@"+self.muc_name,attrs={"type":"error"})
        t1 = Behaviour.MessageTemplate(p)
        b=self.MyJoinRoomBehaviour(self.muc_name,self.name,self.nick,self.password)
        self.myAgent.addBehaviour(b, t1)
        b.join()
        return b.result

    class MyJoinRoomBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,nick,password):
            Behaviour.OneShotBehaviour.__init__(self)
            self.result = False
            self.nick=nick
            self.muc_name=muc_name
            self.name=roomname
            self.password=password

        def _process(self):
            p = Presence(to=self.name+"@"+self.muc_name+"/"+self.nick)
            x = Node(tag="x", attrs={"xmlns":"http://jabber.org/protocol/muc"})
            if self.password!=None:
                pas=Node(tag="password")
                pas.addData(self.password)
                x.addChild(node=pas)
            p.addChild(node=x)
            self.myAgent.jabber.send(p)
            msg=self._receive(True,10)
            if msg:
                    error=msg.getTag("error")
                    if error:
                        self.result = error.getAttr("code")
                        return
            if self.name not in self.myAgent.rooms:
                self.myAgent.rooms.append(self.name)
            self.result = True


    def checkGoal(self,goalList):
        """checks if the goal is valid. must be overloaded"""
        if goalList!=None:
          return True
        else:
          return False


    def checkType(self):
        types=["Flat","Team","Hierarchy"]
        if self.type in types:
                return True
        return False

    def testUnitName(self):
        """checks if the unit exists """
        info=self.getInfo()
        if info:
            if info["parent"]==self.parent:
                return True
        return False

    def invite(self,agentList):
        for agent in agentList:
              message = Node(tag="message", attrs={"to":self.name+"@"+self.muc_name})
              x=Node(tag="x",attrs={"xmlns":"http://jabber.org/protocol/muc#user"})
              y=Node(tag="invite",attrs={"to":agent})
              r=Node(tag="reason")
              r.addData("Inivitation to the Unit "+self.name)
              y.addChild(node=r)
              x.addChild(node=y)
              message.addChild(node=x)
              self.myAgent.jabber.send(message)

    def setGoal(self,goalList):
        """
        Updates unit's goal
          """
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Message(frm=self.name+"@"+self.muc_name, typ="error", attrs={"id":ID})
        t1 = Behaviour.MessageTemplate(p)
        b=self.SetGoalBehaviour(self.muc_name,self.name,goalList,ID)
        self.myAgent.addBehaviour(b, t1)



    class SetGoalBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,goalList,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.goalList=goalList
            self.muc_name=muc_name
            self.name=roomname
            self.ID=ID

        def _process(self):
            m = Message(to=self.name+"@"+self.muc_name, typ="groupchat",attrs={"id":self.ID})
            sub = Node(tag="subject")
            sub.addData(str(self.goalList))
            m.addChild(node=sub)
            self.myAgent.jabber.send(m)
            msg=self._receive(True,10)
            if msg:
                if msg.getType()=="error":
                    raise NotValidGoalChange

    def getGoal(self):
      """
      Returns a list of goals
      """
      if self.state=="unavailable":
        raise Unavailable
        return
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      p = Iq(frm=self.name+"@"+self.muc_name,typ='result', attrs={"id":ID})
      t1 = Behaviour.MessageTemplate(p)
      b=self.GetGoalBehaviour(self.muc_name,self.name,ID)
      self.myAgent.addBehaviour(b, t1)
      b.join()
      return b.result


    class GetGoalBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=None

        def _process(self):
          goal=None
          iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
          query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
          iq.addChild(node=query)
          self.myAgent.jabber.send(iq)
          msg=self._receive(True,10)
          if msg:
            query = msg.getTag("query")
            if query:
              x = query.getTag("x")
              if x:
                  items =x.getChildren()
                  for item in items:
                    if item.getAttr("var")=="muc#roominfo_subject":
                        if item.getTags("value"):
                            goal=item.getTags("value")[0].getData()
          if goal==None:
            print "Not goal"
          self.result=goal

    def getInfo(self):
      """returns info about current unit"""
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      p = Iq(frm=self.name+"@"+self.muc_name,typ='result', attrs={"id":ID})
      t1 = Behaviour.MessageTemplate(p)
      b=self.GetInfoBehaviour(self.muc_name,self.name,ID)
      self.myAgent.addBehaviour(b, t1)
      b.join()
      return b.result

    def getUnitInfo(self,unitname):
      """returns info about the unit unitname"""
      if self.state=="unavailable":
        raise Unavailable
        return
      if unitname not in self.getUnitList():
          raise NotValidUnit
          return
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      p = Iq(frm=unitname+"@"+self.muc_name,typ='result', attrs={"id":ID})
      t1 = Behaviour.MessageTemplate(p)
      b=self.GetInfoBehaviour(self.muc_name,unitname,ID)
      self.myAgent.addBehaviour(b, t1)
      b.join()
      d=b.result
      return d


    class GetInfoBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=None

        def _process(self):
          info={}
          iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
          query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
          iq.addChild(node=query)
          self.myAgent.jabber.send(iq)
          msg=self._receive(True,10)
          if msg:
            query = msg.getTag("query")
            if query:
              x = query.getTag("x")
              if x:
                  items =x.getChildren()
                  for item in items:
                    if item.getAttr("var")=="muc#roominfo_description":
                        if item.getTags("value"):
                            info["type"]=str(item.getTags("value")[0].getData())
                    if item.getAttr("var")=="muc#roominfo_subject":
                        if item.getTags("value"):
                            info["goal"]=str(item.getTags("value")[0].getData())
                    if item.getAttr("var")=="muc#roominfo_type":
                        if item.getTags("value")[0].getData():
                            info["parent"]= str(item.getTags("value")[0].getData().split(":"+self.name)[0])
                    if item.getAttr("var")=="muc#roominfo_lang":
                        if item.getTags("value"):
                            info["contentLanguage"]=str(item.getTags("value")[0].getData())
          self.result=info


    def getMemberList(self):
      """ returns member list"""
      if self.state=="unavailable":
        raise Unavailable
        return
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
      t1 = Behaviour.MessageTemplate(p)
      b=self.GetMemberListBehaviour(self.muc_name,self.name,ID)
      self.myAgent.addBehaviour(b, t1)
      b.join()
      return b.result

    class GetMemberListBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=[]

        def _process(self):
              agents=[]
              iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
              item= Node(tag="item", attrs={"affiliation":"member"})
              query.addChild(node=item)
              iq.addChild(node=query)
              self.myAgent.jabber.send(iq)
              msg=self._receive(True,10)
              if msg:
                  error=msg.getError()
                  if error!=None:
                    print error
                    return
                  query = msg.getTag("query")
                  if query:
                    items =query.getChildren()
                    for item in items:
                        agents.append(str(item.getAttr("jid")))
                    self.result=agents
                    return




    def getNumberOfAgents(self):
      """returns the number of agents that are inside the unit"""
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
      t1 = Behaviour.MessageTemplate(p)
      b=self.GetNumberOfAgentsBehaviour(self.muc_name,self.name,ID)
      self.myAgent.addBehaviour(b, t1)
      b.join()
      return b.result

    class GetNumberOfAgentsBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=None

        def _process(self):
              agents=None
              iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
              query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
              iq.addChild(node=query)
              self.myAgent.jabber.send(iq)
              msg = self._receive(True,10)
              if msg:
                query = msg.getTag("query")
              if query:
                x = query.getTag("x")
                if x:
                    items =x.getChildren()
                    for item in items:
                      if item.getAttr("var")=="muc#roominfo_occupants":
                        agents=item.getTags("value")[0].getData()
              if agents==None:
                print "Error"
              self.result=agents


    def getOwnerList(self):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GetOwnerListBehaviour(self.muc_name,self.name,ID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result

    class GetOwnerListBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=[]

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"owner"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    #items =query.getChildren()
                    owners=[]
                    for item in query:
                        if item.getAttr("jid"):
                            owners.append(str(item.getAttr("jid")))
                    self.result=owners
            return

    def addOwner(self,newAdminJID):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.AddOwnerBehaviour(self.muc_name,self.name,ID,newAdminJID)
        self.myAgent.addBehaviour(b, t)
        b.join()

    class AddOwnerBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,newAdminJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.newAdminJID=newAdminJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"owner","jid":self.newAdminJID})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            print self._receive(True,10)

    def addAdmin(self,newAdminJID):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.AddAdminBehaviour(self.muc_name,self.name,ID,newAdminJID)
        self.myAgent.addBehaviour(b, t)
        b.join()

    class AddAdminBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,newAdminJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.newAdminJID=newAdminJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"admin","jid":self.newAdminJID})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)


    def removeAdmin(self,AdminJID):
            ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
            p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
            t = Behaviour.MessageTemplate(p)
            b=self.RemoveAdminBehaviour(self.muc_name,self.name,ID,AdminJID)
            self.myAgent.addBehaviour(b, t)
            b.join()
            return b.result

    class RemoveAdminBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,newAdminJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.newAdminJID=newAdminJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"member"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            exists=False
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    iqAns = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                    queryAns = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                    for item in query:
                        if str(item.getAttr("jid"))==self.newAdminJID:
                            i=Node(tag="item",attrs={"affiliation":"member","jid":self.newAdminJID})
                            queryAns.addChild(node=i)

                    iqAns.addChild(node=queryAns)
                    self.myAgent.jabber.send(iqAns)
                    msgAns = self._receive(True,10)
                    if msgAns:
                        if msgAns.getAttr("type")!="result":
                            raise NotAllowed
                        else:
                            exists=True
                if not exists:
                    print "The JID "+self.newAdminJID+" doesn't belong to a admin"
                return
            print "Error"#completar un poco el error

    def getAdminList(self):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GetAdminListBehaviour(self.muc_name,self.name,ID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result

    class GetAdminListBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=[]

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"admin"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            while msg and msg.getAttr("id")!=self.ID:
                msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    #items =query.getChildren()
                    owners=[]
                    for item in query:
                        if item.getAttr("jid"):
                            owners.append(str(item.getAttr("jid")))
                    self.result=owners
                    return

    def addModerator(self,newAdminJID):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.AddModeratorBehaviour(self.muc_name,self.name,ID,newAdminJID)
        self.myAgent.addBehaviour(b, t)
        b.join()

    class AddModeratorBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,newAdminJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.newAdminJID=newAdminJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"role":"moderator","jid":self.newAdminJID})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")=="error":
                    raise NotAllowed


    def removeModerator(self,AdminJID):
            ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
            p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
            t = Behaviour.MessageTemplate(p)
            b=self.RemoveModeratorBehaviour(self.muc_name,self.name,ID,AdminJID)
            self.myAgent.addBehaviour(b, t)
            b.join()
            return b.result

    class RemoveModeratorBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,newAdminJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.newAdminJID=newAdminJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"role":"participant","jid":self.newAdminJID})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)

    def getModeratorList(self):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GetModeratorListBehaviour(self.muc_name,self.name,ID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result

    class GetModeratorListBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=[]

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"role":"moderator"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            while msg and msg.getAttr("id")!=self.ID:
                msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    #items =query.getChildren()
                    owners=[]
                    for item in query:
                        if item.getAttr("jid"):
                            owners.append(str(item.getAttr("jid")).split("/")[0])
                    self.result=owners
                    return



    def getParticipantList(self):
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GetParticipantListBehaviour(self.muc_name,self.name,ID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result

    class GetParticipantListBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=[]

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"role":"participant"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            while msg and msg.getAttr("id")!=self.ID:
                msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    #items =query.getChildren()
                    owners=[]
                    for item in query:
                        if item.getAttr("jid"):
                            owners.append(str(item.getAttr("jid")).split("/")[0])
                    self.result=owners
                    return


    def leave(self):
        """
         Agent leaves and it is removed from the member list
          """
        if self.state=="unavailable":
            raise Unavailable
            return
        if self.owner==False:
            p = Presence(to=self.name+"@"+self.muc_name+"/"+self.nick,typ="unavailable")
            self.myAgent.jabber.send(p)
            if self.name in self.myAgent.rooms:
                 self.myAgent.rooms.remove(self.name)
            self.myAgent.removeBehaviour(self)
            self.myAgent.removeBehaviour(self.presenceBehaviour)
            self.state="unavailable"
        else:
            raise LastOwner

    def destroy(self):
      """
     Unit owner destroys the unit
      """
      if self.state=="unavailable":
          raise Unavailable
          return
      units=self.getSubUnitList(self.name)
      units.append(self.name)
      if self.owner==True:
          for u in units:
                  ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
                  p = Iq(frm=u+"@"+self.muc_name, attrs={"id":ID})
                  t1 = Behaviour.MessageTemplate(p)
                  b=self.DestroyBehaviour(self.muc_name,u,ID)
                  self.myAgent.addBehaviour(b, t1)
                  b.join()
          #eliminar del DF
          dad = DF.DfAgentDescription()
          dad.setAID(self.myAgent.getAID())
          search = self.myAgent.searchService(dad)
          if search:
              newdad=DF.DfAgentDescription()
              newdad.setAID(self.myAgent.getAID())
              for d in search[0].getServices():
                  if d.getName()!=self.name:
                      newdad.addService(d)
              self.myAgent.deregisterService(dad)
              self.myAgent.registerService(newdad)
          if self.name in self.myAgent.rooms:
                self.myAgent.rooms.remove(self.name)
          self.myAgent.removeBehaviour(self.presenceBehaviour)
          if self.requestBehaviour:
              self.myAgent.removeBehaviour(self.requestBehaviour)
          self.myAgent.removeBehaviour(self)
          self.state="unavailable"
          #destruir las unidades
      else:
          raise DestroyError



    class DestroyBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=False

        def _process(self):
          iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
          query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
          item= Node(tag="destroy")
          query.addChild(node=item)
          iq.addChild(node=query)
          self.myAgent.jabber.send(iq)
          msg = self._receive(True,10)
          if msg:
            if msg.getAttr("type")!="result":
              print msg.getError()
              return
            else:
              self.result=True
              return
          print "Error: el mensaje no se ha recibido"

    class PresenceBehaviour(Behaviour.Behaviour):
        def __init__(self,muc_name,roomname,nick,unit):
            Behaviour.Behaviour.__init__(self)
            self.muc_name=muc_name
            self.name=roomname
            self.nick=nick
            self.unit=unit


        def _process(self):
            msg = self._receive(True)
            if msg:
                if msg.getType()=="unavailable":
                    if msg.getRole()=="none" and msg.getFrom()==self.name+"@"+self.muc_name+"/"+self.nick:
                        x=msg.getTag("x")
                        if x:
                            self.unit.state="unavailable"
                            destroy=x.getTag("destroy")
                            if destroy:
                                print "The room "+self.name+" has been destroyed"
                                if self.unit.owner:
                                    #eliminar del df
                                      time.sleep(random.randint(1,10))
                                      dad = DF.DfAgentDescription()
                                      dad.setAID(self.myAgent.getAID())
                                      search = self.myAgent.searchService(dad)
                                      if search:
                                          newdad=DF.DfAgentDescription()
                                          newdad.setAID(self.myAgent.getAID())
                                          for d in search[0].getServices():
                                              if d.getName()!=self.name and d.getType()!="ORGANIZATION" and d.getType()!="UNIT":
                                                  newdad.addService(d)
                                          self.myAgent.deregisterService(dad)
                                          self.myAgent.registerService(newdad)
                        if msg.getStatusCode()=="301":
                                print "You have been baned"
                        if msg.getStatusCode()=="307":
                                print "You have been kicked"
                        #elimnamos las salas que tenemos dentro
                        units=[]
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        parent=self.unit.parent+":"+self.unit.name
                        if search:
                              for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent" and parent in p["value"].strip("u'"):
                                              units.append(parent+":"+str(d.getName()))
                                          if "Team:" in self.unit.name and (self.unit.parent_type=="Federation" or self.unit.parent_type=="Matrix"):
                                              #si te han explusado del equipo de supervisores añadimos tus salas propias
                                              if p["name"].strip("u'")=="parent" and self.unit.parent== p["value"].strip("u'"):
                                                  units.append(self.unit.parent+":"+str(d.getName()))

                        #units contiene la lista con las unidades descendientes que pertenecen al agente expulsado
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        if search:
                            for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent" and p["value"].strip("u'") in units:
                                              units.append(str(d.getName()))
                        for u in units:
                              iq = Iq(to=u+"@"+self.muc_name,typ='set')
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
                              item= Node(tag="destroy")
                              query.addChild(node=item)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                        if self.unit.requestBehaviour:
                                      self.myAgent.removeBehaviour(self.unit.requestBehaviour)
                        self.myAgent.removeBehaviour(self.unit)
                        self.myAgent.removeBehaviour(self)
                        if self.name in self.myAgent.rooms:
                                self.myAgent.rooms.remove(self.name)
                        raise Unavailable
                    else:
                            jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                            if jid in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.remove(jid)
                                  if self.unit.type=="Team" and self.unit.owner:
                                      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
                                      p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
                                      t1 = Behaviour.MessageTemplate(p)
                                      b=self.MinAgentsBehaviour(self.muc_name,self.name,ID,self.unit)
                                      self.myAgent.addBehaviour(b, t1)
                else:
                        jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                        if jid not in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.append(jid)
                                  if self.unit.type in ["Team","Flat"] and self.unit.owner:
                                      self.unit.addAdmin(jid)
                                      self.unit.removeModerator(jid)
                                      #si es un equipo hay que controlar los numeros máximos y mínimos
                                      if self.unit.type=="Team":
                                          ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
                                          p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
                                          t1 = Behaviour.MessageTemplate(p)
                                          b=self.MinAgentsBehaviour(self.muc_name,self.name,ID,self.unit)
                                          self.myAgent.addBehaviour(b, t1)

        class MinAgentsBehaviour(Behaviour.OneShotBehaviour):
            def __init__(self,muc_name,roomname,ID,unit):
                Behaviour.OneShotBehaviour.__init__(self)
                self.ID=ID
                self.muc_name=muc_name
                self.name=roomname
                self.result=[]
                self.unit=unit

            def _process(self):
                minAgents="0"
                iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
                iq.addChild(node=query)
                self.myAgent.jabber.send(iq)
                msg = self._receive(True,10)
                if msg:
                  query = msg.getTag("query")
                  if query:
                    x = query.getTag("x")
                    if x:
                        items =x.getChildren()
                        for item in items:
                              if item.getAttr("var")=="muc#roominfo_minusers":
                                   minAgents=item.getTags("value")[0].getData()
                  agents="0"
                  iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                  query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
                  iq.addChild(node=query)
                  self.myAgent.jabber.send(iq)
                  msg = self._receive(True,10)
                  if msg:
                    query = msg.getTag("query")
                  if query:
                    x = query.getTag("x")
                    if x:
                        items =x.getChildren()
                        for item in items:
                          if item.getAttr("var")=="muc#roominfo_occupants":
                            agents=item.getTags("value")[0].getData()
                  if agents and minAgents and int(agents)<int(minAgents):
                      iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                      query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                      item= Node(tag="item", attrs={"role":"participant"})
                      query.addChild(node=item)
                      iq.addChild(node=query)
                      self.myAgent.jabber.send(iq)
                      msg=self._receive(True,10)
                      if msg:
                          error=msg.getError()
                          if error!=None:
                            print error
                            return
                          q = msg.getTag("query")
                          if q:
                              iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                              items =q.getChildren()
                              for item in items:
                                  i= Node(tag="item", attrs={"jid":str(item.getAttr("jid")),"role":"visitor"})
                                  query.addChild(node=i)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                              self.unit.state="locked"
                if agents and minAgents and int(agents)>int(minAgents) and self.unit.state=="locked":
                      iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                      query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                      item= Node(tag="item", attrs={"role":"visitor"})
                      query.addChild(node=item)
                      iq.addChild(node=query)
                      self.myAgent.jabber.send(iq)
                      msg=self._receive(True,10)
                      if msg:
                          error=msg.getError()
                          if error!=None:
                            print error
                            return
                          q = msg.getTag("query")
                          if q:
                              iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                              items =q.getChildren()
                              for item in items:
                                  i= Node(tag="item", attrs={"jid":str(item.getAttr("jid")),"role":"visitor"})
                                  query.addChild(node=i)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                              self.unit.state="available"

    def kickAgent(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.KickAgentBehaviour(self.muc_name,self.name,ID,jid)
        self.myAgent.addBehaviour(b, t)
        b.join()
        if b.result!=None:
            raise b.result

    class KickAgentBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,jid):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.jid=jid
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"role":"none","jid":self.jid})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                   self.result=NotAllowed

    def addBanAgent(self,agentJID):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.AddBanAgentBehaviour(self.muc_name,self.name,ID,agentJID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        if b.result!=None:
            raise b.result

    class AddBanAgentBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,agentJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.agentJID=agentJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"outcast","jid":self.agentJID})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    self.result=NotAllowed

    def removeBanAgent(self,agentJID):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.RemoveBanAgentBehaviour(self.muc_name,self.name,ID,agentJID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result

    class RemoveBanAgentBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,agentJID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.agentJID=agentJID
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"outcast"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            exists=False
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    iqAns = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                    queryAns = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                    for item in query:
                        if item.getAttr("jid")==self.agentJID:
                            i= Node(tag="item", attrs={"affiliation":"none","jid":self.agentJID})
                            queryAns.addChild(node=i)
                            exists=True
                    iqAns.addChild(node=queryAns)
                    self.myAgent.jabber.send(iqAns)
                    msgAns = self._receive(True,10)
                    if msgAns:
                        if msgAns.getAttr("type")!="result":
                            print msgAns.getError() #completar un poco el error
                    if not exists:
                        print "The JID "+self.agentJID+" doesn't belong to a banned agent"
                return
            print "Error"#completar un poco el error

    def getBanAgentList(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GetBanAgentListBehaviour(self.muc_name,self.name,ID)
        self.myAgent.addBehaviour(b, t)
        b.join()
        return b.result

    class GetBanAgentListBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=None

        def _process(self):
            BanedList=[]
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"affiliation":"outcast"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    print msg.getError() #completar un poco el error
                    return
                query = msg.getQueryChildren()
                if query:
                    for item in query:
                        if item.getAttr("jid"):
                            BanedList.append(str(item.getAttr("jid")))
                    self.result=BanedList


    def giveVoice(self,name):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GiveVoiceBehaviour(self.muc_name,self.name,ID,name)
        self.myAgent.addBehaviour(b, t)
        b.join()
        if b.result!=None:
            raise b.result

    class GiveVoiceBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,name):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.name=name
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"jid":self.name,"role":"participant"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    self.result=NotAllowed

    def revokeVoice(self,name):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.RevokeVoiceBehaviour(self.muc_name,self.name,ID,name)
        self.myAgent.addBehaviour(b, t)
        b.join()
        b.join()
        if b.result!=None:
            raise b.result

    class RevokeVoiceBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,name):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.name=name
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"jid":self.name,"role":"visitor"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    self.result=NotAllowed



    def sendMessage(self,message):
        if self.state=="unavailable":
            raise Unavailable
            return
        p=Message(frm=self.name+"@"+self.muc_name,typ="error")
        t = Behaviour.MessageTemplate(p)
        b=self.SendMessageBehaviour(self.muc_name,self.name,self.nick,message,self.type)
        self.myAgent.addBehaviour(b, t)
        b.join()
        if b.result!=None:
            raise b.result()

    class SendMessageBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,nick,message,type):
            Behaviour.OneShotBehaviour.__init__(self)
            self.muc_name=muc_name
            self.name=roomname
            self.nick=nick
            self.ACLmsg=message
            self.type=type
            self.result=None

        def _process(self):
            self.ACLmsg.setProperty("from",self.name)
            if self.type=="Hierarchy":
                jid=self.name+"@"+self.muc_name+"/"+self.nick
            else:
                jid=self.myAgent.JID
            aid=AID.aid(jid,["xmpp://"+jid])
            self.ACLmsg.setSender(aid)
            content = self.ACLmsg.getContent()
            comillas_esc = '\\"'
            barrainv_esc = '\\\\'
            mtmp1 = barrainv_esc.join(content.split('\\'))
            mtmp2 = comillas_esc.join(mtmp1.split('"'))
            payload_esc = mtmp2
            self.ACLmsg.setContent(payload_esc)

            ap = ACLParser.ACLxmlParser()
            payload = ap.encodeXML(self.ACLmsg)

            envelope = Envelope.Envelope()
            envelope.setFrom(self.ACLmsg.getSender())
            envelope.setAclRepresentation("fipa.acl.rep.xml.std")
            envelope.setPayloadLength(len(payload))
            envelope.setPayloadEncoding("US-ASCII")
            envelope.setDate(BasicFipaDateTime.BasicFipaDateTime())


            xc = XMLCodec.XMLCodec()
            envxml = xc.encodeXML(envelope)

            xenv = Node('jabber:x:fipa x')
            xenv['content-type']='fipa.mts.env.rep.xml.std'
            xenv.addData(envxml)
            jabber_msg = Message(self.name+"@"+self.muc_name, payload, xmlns="",typ="groupchat")
            jabber_msg.addChild(node=xenv)
            self.myAgent.jabber.send(jabber_msg)
            msg = self._receive(True,10)
            if msg:
                print "This message can't be sent"
                self.result=NotAllowed

    def sendPrivateMessage(self,message,recName):
        if self.state=="unavailable":
            raise Unavailable
            return
        p=Message(frm=self.name+"@"+self.muc_name,typ="error")
        t = Behaviour.MessageTemplate(p)
        b=self.SendPrivateMessageBehaviour(recName,message,self.name,self.muc_name,self.nick,type)
        self.myAgent.addBehaviour(b, t)
        b.join()
        if b.result!=None:
            raise b.result()

    class SendPrivateMessageBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,recName,message,name,muc_name,nick,type):
            Behaviour.OneShotBehaviour.__init__(self)
            self.recName=recName
            self.ACLmsg=message
            self.name=name
            self.nick=nick
            self.muc_name=muc_name
            self.type=type
            self.result=None

        def _process(self):
            self.ACLmsg.setProperty("from",self.name)
            if self.type=="Hierarchy":
                jid=self.name+"@"+self.muc_name+"/"+self.nick
            else:
                jid=self.myAgent.JID
            aid=AID.aid(jid,["xmpp://"+jid])
            self.ACLmsg.setSender(aid)
            content = self.ACLmsg.getContent()
            comillas_esc = '\\"'
            barrainv_esc = '\\\\'
            mtmp1 = barrainv_esc.join(content.split('\\'))
            mtmp2 = comillas_esc.join(mtmp1.split('"'))
            payload_esc = mtmp2
            self.ACLmsg.setContent(payload_esc)

            ap = ACLParser.ACLxmlParser()
            payload = ap.encodeXML(self.ACLmsg)

            envelope = Envelope.Envelope()
            envelope.setFrom(self.ACLmsg.getSender())
            for i in self.ACLmsg.getReceivers():
                envelope.addTo(i)
            envelope.setAclRepresentation("fipa.acl.rep.xml.std")
            envelope.setPayloadLength(len(payload))
            envelope.setPayloadEncoding("US-ASCII")
            envelope.setDate(BasicFipaDateTime.BasicFipaDateTime())


            xc = XMLCodec.XMLCodec()
            envxml = xc.encodeXML(envelope)

            xenv = Node('jabber:x:fipa x')
            xenv['content-type']='fipa.mts.env.rep.xml.std'
            xenv.addData(envxml)
            jabber_msg = Message(self.recName, payload, xmlns="",typ="chat")
            jabber_msg.addChild(node=xenv)
            self.myAgent.jabber.send(jabber_msg)
            msg = self._receive(True,10)
            if msg:
                print "This message can't be sent"
                self.result=NotAllowed

    def receiveMessage(self,debug=False):
        if self.state=="unavailable":
            raise Unavailable
            return
        msg = self._receive(True,10)
        while msg and (msg.getProperty("from")!=self.name or msg.getOntology()=="spade:x:unit"):
            msg=None
            msg = self._receive(True,10)
            if debug:
                print msg
        return msg

    def unitTemplate(self):
        template = Behaviour.ACLTemplate()
        template.setProperty("from",self.name)
        t = Behaviour.MessageTemplate(template)
        self.setTemplate(t)

    def addUnit(self,unit):
        """
        Creates a new unit inside an organization
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        if self.checkTypes(self.parent_type,unit.type):
            if self.checkCreationPermission():
                     unit.create=True
                     unit.parent=self.parent+":"+self.name
                     unit.parent_type=self.parent_type
                     self.orgOwner=self.getOwnerList()
                     unit.orgOwner=self.orgOwner
                     unit.create=True
                     result=unit.myCreate()
                     if result==True:
                         self.myAgent.addBehaviour(unit)
                         unit.unitTemplate()
                     else:
                         raise result
            else:
                 raise NotCreatePermission
        else:
          raise NotValidType

    def joinUnit(self,unit):
        """
        Agent joins a unit
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        if unit.name not in self.getUnitList():
            raise NotValidUnit
            return
        if unit.type!=self.getUnitInfo(unit.name)["type"]:
            raise NotValidType
            return
        unit.create=False
        unit.parent=self.parent+":"+self.name
        result=unit.myJoin()
        if result==True:
            self.myAgent.addBehaviour(unit)
            unit.unitTemplate()
        else:
            raise result




    def checkTypes(self,orgType,unitType):
        if orgType=="Flat":
          return True
        if orgType=="Team" and unitType=="Team":
          return True
        if orgType=="Hierarchy" and unitType=="Hierarchy":
          return True
        if orgType=="Bureaucracy" and unitType=="Hierarchy":
          return True
        if orgType=="Matrix" and unitType=="Hierarchy":
          return True
        if orgType=="Federation" and unitType=="Hierarchy":
          return True
        if orgType=="Coalition" and unitType=="Team":
          return True
        if orgType=="Congregation" and unitType=="Hierarchy":
          return True
        if orgType=="Congregation" and unitType=="Team":
          return True
        if orgType=="Congregation" and unitType=="Flat":
          return True
        return False

    def checkIsMember(self,unitList):
        list=self.myAgent.rooms
        print "Unidades de la organizacion ",unitList
        print "Unidades a las que pertenece", list
        for u in unitList:
            if u in list:
                return True
        return False

    class CheckIsMemberBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,ID,jid):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.jid=jid
            self.result=[]

        def _process(self):
          iq = Iq(to=self.jid,typ='get', attrs={"id":self.ID})
          query = Protocol('query',xmlns="http://jabber.org/protocol/disco#items",attrs={"node":"http://jabber.org/protocol/muc#rooms"})
          iq.addChild(node=query)
          self.myAgent.jabber.send(iq)
          msg = self._receive(True,10)
          if msg:
                print msg
                items =msg.getChildren()
                for item in items:
                    if item.getAttr("jid"):
                        sala=str(item.getAttr("jid"))
                        self.result.append(sala.split('@')[0])

    def getUnitList(self):
      """
      Returns a list of the units
      """
      if self.state=="unavailable":
        raise Unavailable
        return
      l=[]
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      dad.addService(ds)
      if self.parent=="":
          parent=self.name
      else:
          parent=self.parent+":"+self.name
      search = self.myAgent.searchService(dad)
      cont=1
      while cont<=3 and not search:
          cont=cont+1
          search = self.myAgent.searchService(dad)
      if search:
          for d in search:
              for s in d.getServices():
                  prop=s.getProperties()
                  for p in prop:
                      if p["name"].strip("u'")=="parent" and p["value"].strip("u'")==parent:
                          l.append(str(s.getName()))
      return l

    def getSubUnitList(self,unitName):
      """Returns all the units that have been definide inisde current unit"""
      l=[]
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      dad.addService(ds)
      search = self.myAgent.searchService(dad)
      if search:
          for d in search:
                  for s in d.getServices():
                          prop=s.getProperties()
                          for p in prop:
                              if p["name"].strip("u'")=="parent" and unitName in p["value"].strip("u'"):
                                  l.append(str(s.getName()))
      return l

    """
    def run(self):
            self.onStart()
            while (not self.done()) and (not self._forceKill.isSet()):
                self._process()
                #time.sleep(0)
            self.onEnd()
            if self.name in self.myAgent.rooms:
                self.myAgent.rooms.remove(self.name)
            self.myAgent.removeBehaviour(self)
"""
    def requestEntryUnit(self,unit,dataForm=[]):
      if self.state=="unavailable":
          raise Unavailable
          return
      if unit not in self.getUnitList():
          raise NotValidUnit
          print unit," list:",list
          return
      #consultar en el DF quien es el owner de la organizaciÃ³n
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      ds.setName(unit)
      dad.addService(ds)
      search = self.myAgent.searchService(dad)
      if search:
          owner=search[0].getAID()
          #comportammiento con mensaje ACL solicitando permiso
          ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
          template = Behaviour.ACLTemplate()
          template.setSender(owner)
          template.setPerformative("inform")
          template.setOntology("spade:x:unit")
          template.setProperty("from",unit)
          template.setConversationId(ID)
          t = Behaviour.MessageTemplate(template)
          self.setTemplate(t)
          b=self.RequestEntryBehaviour(owner,unit,dataForm,ID)
          self.myAgent.addBehaviour(b, t)
          b.join()
          return b.result

    class RequestEntryBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,owner,roomname,desc,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.owner=owner
            self.name=roomname
            self.desc=desc
            self.ID=ID
            self.result=False

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="Entry"
            if self.desc:
                desc["desc"]=self.desc
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            msg.addReceiver(self.owner)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                if "Allowed:" in ans.getContent():
                   self.result=ans.getContent().split(":")[1]
                elif "Allowed" in ans.getContent():
                    self.result=True

    def requestDataForm(self,unit):
      if self.state=="unavailable":
          raise Unavailable
          return
      if unit not in self.getUnitList():
          raise NotValidUnit
          return
      #consultar en el DF quien es el owner de la organización
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      ds.setName(unit)
      dad.addService(ds)
      search = self.myAgent.searchService(dad)
      if search:
          owner=search[0].getAID()
          #comportammiento con mensaje ACL solicitando permiso
          ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
          template = Behaviour.ACLTemplate()
          template.setSender(owner)
          template.setPerformative("inform")
          template.setOntology("spade:x:unit")
          template.setProperty("from",unit)
          template.setConversationId(ID)
          t = Behaviour.MessageTemplate(template)
          b=self.RequestDataFormBehaviour(owner,unit,ID)
          self.myAgent.addBehaviour(b, t)
          b.join()
          return b.result

    class RequestDataFormBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,owner,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.owner=owner
            self.name=roomname
            self.ID=ID
            self.result=[]

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="DataForm"
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            msg.addReceiver(self.owner)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                   self.result=eval(ans.getContent())

    def addDataFormItem(self,name,desc):
        if self.state=="unavailable":
          raise Unavailable
          return
        if not self.owner:
            raise NotAllowed
            return
        for i in self.dataForm:
            if i["name"]==name:
                raise NotValidItem
                return
        self.dataForm.append({"name":name,"description":desc,"value":""})

    def removeDataFormItem(self,name):
        if self.state=="unavailable":
          raise Unavailable
          return
        if not self.owner:
            raise NotAllowed
            return
        l=[]
        for i in self.dataForm:
            if i["name"]!=name:
                l.append(i)
        self.dataForm=l

    def getDataFormItems(self):
        if self.state=="unavailable":
          raise Unavailable
          return
        if not self.owner:
            raise NotAllowed
            return
        return self.dataForm







    def _process(self):
        pass





class Hierarchy(Unit):
    def __init__(self,agent, nick, name,password, goalList=[], agentList=[],contentLanguage="sl",create=True):
        Unit.__init__(self,agent, nick, name, "Hierarchy", goalList, agentList, contentLanguage,password,create)


    def myCreate(self):
          if not self.checkGoal(self.goalList):
              return NotValidGoal
          elif not self.checkType():
              return NotValidType
          elif self.password==None:
              return PaswordNeeded
          elif not self.testRoomName():
              return NotValidName
          elif not self.createRoom():
              return CreationError
          else:
              self.state="available"
              self.owner=True
              if self.agentList!=[]:
                #add members to unit
                for a in self.agentList:
                  self.addMember(a)
              #registering the unit service
              dad = DF.DfAgentDescription()
              dad.setAID(self.myAgent.getAID())
              search = self.myAgent.searchService(dad)
              if search:
                  dad=search[0]
                  d = DF.DfAgentDescription()
                  d.setAID(self.myAgent.getAID())
                  self.myAgent.deregisterService(d)
              else:
                  dad = DF.DfAgentDescription()
                  dad.setAID(self.myAgent.getAID())
              ds = DF.ServiceDescription()
              ds.setType("UNIT")
              ds.setName(self.name)
              ds.addProperty({"name":"parent","value":self.parent})
              dad.addService(ds)
              res = self.myAgent.registerService(dad)
              cont=0
              while not res and cont<3:
                 res = self.myAgent.registerService(dad)
                 cont=cont+1
              if not res: return CreationError
              #Unit message template
              template = Behaviour.ACLTemplate()
              template.setProperty("from",self.name)
              t = Behaviour.MessageTemplate(template)
              self.setTemplate(t)
              #Presence Template and Behaviour
              p = Presence(frm=self.name+"@"+self.muc_name)
              t = Behaviour.MessageTemplate(p)
              self.presenceBehaviour=self.PresenceBehaviour(self.muc_name,self.name,self.nick,self)
              self.myAgent.addBehaviour(self.presenceBehaviour, t)
              #Request template and behaviour
              template = Behaviour.ACLTemplate()
              template.setProperty("from",self.name)
              template.setPerformative("request")
              template.setOntology("spade:x:unit")
              t = Behaviour.MessageTemplate(template)
              self.requestBehaviour=self.RequestBehaviour(self)
              self.myAgent.addBehaviour(self.requestBehaviour, t)
              #items del dataForm
              self.dataForm=[]
              return True


    def joinUnit(self,unit):
        if self.parent_type!="Bureaucracy" and self.parent_type!="Federation":
            Unit.joinUnit(self,unit)
        #if it is a federation or bureaucracy and agent can't be in more than one unit
        else:
            if self.owner==True or self.myAgent.JID in self.getAdminList():
                raise NotAllowed
            else:
                Unit.joinUnit(self,unit)
                self.leave()

    def requestCreationPermission(self,desc=None):
      if self.state=="unavailable":
          raise Unavailable
          return
      if self.owner:
          return True
      #consultar en el DF quien es el owner de la organización
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      ds.setName(self.name)
      dad.addService(ds)
      search = self.myAgent.searchService(dad)
      if search:
          owner=search[0].getAID()
          #comportammiento con mensaje ACL solicitando permiso
          ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
          template = Behaviour.ACLTemplate()
          template.setSender(owner)
          template.setPerformative("inform")
          template.setOntology("spade:x:unit")
          template.setProperty("from",self.name)
          template.setConversationId(ID)
          t = Behaviour.MessageTemplate(template)
          b=self.RequestCreationPermissionBehaviour(owner,self.name,desc,ID)
          self.myAgent.addBehaviour(b, t)
          b.join()
          return b.result
      else:
          return False


    class RequestCreationPermissionBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,owner,roomname,desc,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.owner=owner
            self.name=roomname
            self.desc=desc
            self.ID=ID
            self.result=False

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="RoomCreation"
            if self.desc:
                desc["desc"]=self.desc
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            msg.addReceiver(self.owner)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                if ans.getContent()=="Allowed":
                   self.result=True



    def requestCommunicationAbility(self,desc=None):
      if self.state=="unavailable":
          raise Unavailable
          return
      #consultar en el DF quien es el owner de la organización
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      ds.setName(self.name)
      dad.addService(ds)
      search = self.myAgent.searchService(dad)
      owner=search[0].getAID()
      #comportammiento con mensaje ACL solicitando permiso
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      template = Behaviour.ACLTemplate()
      template.setSender(owner)
      template.setPerformative("inform")
      template.setOntology("spade:x:unit")
      template.setProperty("from",self.name)
      template.setConversationId(ID)
      t = Behaviour.MessageTemplate(template)
      b=self.RequestVoiceBehaviour(owner,self.name,desc,ID)
      self.myAgent.addBehaviour(b, t)
      b.join()
      return b.result

    class RequestVoiceBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,owner,roomname,desc,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.owner=owner
            self.name=roomname
            self.desc=desc
            self.ID=ID
            self.result=False

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="Voice"
            if self.desc:
                desc["desc"]=self.desc
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            msg.addReceiver(self.owner)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                if ans.getContent()=="Allowed":
                   self.result=True




    class RequestBehaviour(Behaviour.Behaviour):
        def __init__(self,organization):
            Behaviour.Behaviour.__init__(self)
            self.organization=organization

        def _process(self):
            m= self._receive(True)
            if m and str(m.getProperty("from"))==self.organization.name:
                #print "Mensaje de peticion "+str(m)
                sender=m.getSender()
                d=eval(m.getContent())
                desc=None
                if d.has_key("desc"): desc=d["desc"]
                ID=m.getConversationId()
                if "RoomCreation"==d["main"]:
                    allow=self.organization.creationPermissionTest(sender.getName(),desc)
                    if allow:
                        self.organization.giveCreationPermission(sender.getName())
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                    else:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Not-Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                elif "Voice"==d["main"]:
                    allow=self.organization.communicationAbilityTest(sender.getName(),desc)
                    if allow:
                        self.organization.giveVoice(sender.getName())
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                    else:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Not-Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                elif "Entry"==d["main"]:
                    allow=self.organization.entryUnitTest(sender.getName(),desc)
                    if allow:
                        self.organization.addMember(sender.getName())
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Allowed:"+self.organization.password)
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                    else:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Not-Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                elif "DataForm"==d["main"]:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent(str(self.organization.dataForm))
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)



    def creationPermissionTest(self,sender,desc):
        "Metodo que permite definir cuando se permite la creación de salas. Hay que sobrecargar"
        return False

    def communicationAbilityTest(self,sender,desc):
        "Metodo que permite definir cuando se permite la creación de salas. Hay que sobrecargar"
        return False

    def entryUnitTest(self,sender,desc):
        "Metodo que permite definir cuando se permite la creación de salas. Hay que sobrecargar"
        return False

    def addMember(self,agent):
        self.invite([agent])
        self.revokeVoice(agent)




    def giveCommunicationAbility(self,name):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.GiveVoiceBehaviour(self.muc_name,self.name,ID,name)
        self.myAgent.addBehaviour(b, t)
        b.join()

    class GiveVoiceBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,name):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.name=name
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"jid":self.name,"role":"participant"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    raise NotAllowed

    def revokeCommunicationAbility(self,nickname):
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t = Behaviour.MessageTemplate(p)
        b=self.RevokeVoiceBehaviour(self.muc_name,self.name,ID,nickname)
        self.myAgent.addBehaviour(b, t)
        b.join()

    class RevokeVoiceBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,nickname):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.nickname=nickname
            self.result=None

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
            item= Node(tag="item", attrs={"jid":self.nickname,"role":"visitor"})
            query.addChild(node=item)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
                if msg.getAttr("type")!="result":
                    raise NotAllowed

    def getGoal(self):
        return Unit.getGoal(self)

    def getUnitList(self):
        return Unit.getUnitList(self)

    def getUnitInfo(self,unit):
        return Unit.getUnitInfo(self,unit)

    def giveCreationPermission(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        self.addAdmin(jid)

    def revokeCreationPermission(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        self.removeAdmin(jid)

    def expulsion(self,Agentjid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        Unit.kickAgent(self,Agentjid)

    def permanentExpulsion(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        Unit.addBanAgent(self,jid)

    def revokePermanentExpulsion(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        Unit.removeBanAgent(self,jid)
    def getPermanentExpulsionList(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        return Unit.getBanAgentList()

    def getMemberList(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        mem=[]
        for m in self.members:
            mem.append(str(m).split("/")[0])

        return mem

    def getNumberOfAgents(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        return Unit.getNumberOfAgents(self)

    def setGoal(self,goalList):
        """
        Updates organization goals
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        Unit.setGoal(self,goalList)

    def invite(self,agentList):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        Unit.invite(self,agentList)

    def checkCreationPermission(self):
        if self.owner==True:
                return True
        else:
            adminList=self.getAdminList()
            try:
              adminList.index(self.myAgent.JID)
            except:
                    return False
            return True


    class PresenceBehaviour(Behaviour.Behaviour):
        def __init__(self,muc_name,roomname,nick,unit):
            Behaviour.Behaviour.__init__(self)
            self.muc_name=muc_name
            self.name=roomname
            self.nick=nick
            self.unit=unit


        def _process(self):
            msg = self._receive(True)
            if msg:
                if msg.getType()=="unavailable":
                    if msg.getRole()=="none" and msg.getFrom()==self.name+"@"+self.muc_name+"/"+self.nick:
                        x=msg.getTag("x")
                        if x:
                            self.unit.state="unavailable"
                            destroy=x.getTag("destroy")
                            if destroy:
                                print "The room "+self.name+" has been destroyed"
                                if self.unit.owner:
                                    #eliminar del df el servicio
                                      time.sleep(random.randint(1,10))
                                      dad = DF.DfAgentDescription()
                                      dad.setAID(self.myAgent.getAID())
                                      search = self.myAgent.searchService(dad)
                                      if search:
                                          newdad=DF.DfAgentDescription()
                                          newdad.setAID(self.myAgent.getAID())
                                          for d in search[0].getServices():
                                              if d.getName()!=self.name and d.getType()!="ORGANIZATION" and d.getType()!="UNIT":
                                                  newdad.addService(d)
                                          self.myAgent.deregisterService(dad)
                                          self.myAgent.registerService(newdad)
                        if msg.getStatusCode()=="301":
                                print "You have been baned"
                        if msg.getStatusCode()=="307":
                                print "You have been kicked"

                        units=[]
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        name=self.unit.name
                        if search:
                              for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent" and name in p["value"].strip("u'"):
                                              units.append(str(d.getName()))

                        #units contiene la lista con las unidades descendientes que pertenecen al agente expulsado
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        if search:
                            for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent":
                                              for u in units:
                                                  if u in p["value"].strip("u'") and d.getName() not in units:
                                                      units.append(str(d.getName()))
                        for u in units:
                              iq = Iq(to=u+"@"+self.muc_name,typ='set')
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
                              item= Node(tag="destroy")
                              query.addChild(node=item)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                        if self.unit.requestBehaviour:
                            self.myAgent.removeBehaviour(self.unit.requestBehaviour)
                        if self.name in self.myAgent.rooms:
                            self.myAgent.rooms.remove(self.name)
                        self.myAgent.removeBehaviour(self.unit)
                        self.myAgent.removeBehaviour(self)
                        #raise Unavailable
                    else:
                        #otro agente ha dejado la unidad
                            jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                            if jid in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.remove(jid)
                else:
                    #otro agente ha entrado en la unidad
                        jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                        if jid not in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.append(jid)






class Flat(Unit):
    def __init__(self, agent,nick, name,password=None, goalList=[], agentList=[],contentLanguage="sl",create=True):
        self.leader=False
        self.password=None
        Unit.__init__(self,agent, nick, name, "Flat", goalList, agentList, contentLanguage,password,create)


    def myCreate(self):
          if not self.checkGoal(self.goalList):
              return NotValidGoal
          elif not self.checkType():
              return NotValidType
          elif not self.testRoomName():
              return NotValidName
          elif not self.createRoom():
              return CreationError
          else:
              self.state="available"
              if self.agentList!=[]:
            #enviando invitaciones
                for a in self.agentList:
                  self.addMember(a)

              dad = DF.DfAgentDescription()
              dad.setAID(self.myAgent.getAID())
              search = self.myAgent.searchService(dad)
              if search:
                  dad=search[0]
                  d = DF.DfAgentDescription()
                  d.setAID(self.myAgent.getAID())
                  self.myAgent.deregisterService(d)
              else:
                  dad = DF.DfAgentDescription()
                  dad.setAID(self.myAgent.getAID())
              ds = DF.ServiceDescription()
              ds.setType("UNIT")
              ds.setName(self.name)
              ds.addProperty({"name":"parent","value":self.parent})
              dad.addService(ds)
              res = self.myAgent.registerService(dad)
              cont=0
              while not res and cont<3:
                 res = self.myAgent.registerService(dad)
                 cont=cont+1
              if not res: return CreationError
              self.owner=True
              template = Behaviour.ACLTemplate()
              template.setProperty("from",self.name)
              t = Behaviour.MessageTemplate(template)
              self.setTemplate(t)
              p = Presence(frm=self.muc_name)
              t = Behaviour.MessageTemplate(p)
              self.presenceBehaviour=self.PresenceBehaviour(self.muc_name,self.name,self.nick,self)
              self.myAgent.addBehaviour(self.presenceBehaviour, t)
              template = Behaviour.ACLTemplate()
              template.setProperty("from",self.name)
              template.setPerformative("request")
              template.setOntology("spade:x:unit")
              t = Behaviour.MessageTemplate(template)
              self.requestBehaviour=self.RequestBehaviour(self)
              self.myAgent.addBehaviour(self.requestBehaviour, t)
              #items del dataForm
              self.dataForm=[]
              return True



    def getMemberList(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        admins=Unit.getAdminList(self)
        owner=Unit.getOwnerList(self)
        moderator=Unit.getParticipantList(self)
        for o in owner:
            if o in moderator:
                admins.append(o)
        return admins

    def getNumberOfAgents(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        return Unit.getNumberOfAgents(self)

    def setGoal(self,goalList):
        """
        Updates organization goals
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        Unit.setGoal(self,goalList)




    def checkCreationPermission(self):
            return True



    def addMember(self,agent):
        self.invite([agent])
        self.addAdmin(agent)

    def requestEntryUnit(self,unit,dataForm):
        return True

    class RequestBehaviour(Behaviour.Behaviour):
        def __init__(self,organization):
            Behaviour.Behaviour.__init__(self)
            self.organization=organization

        def _process(self):
            m= self._receive(True)
            if m and str(m.getProperty("from"))==self.organization.name:
                #print "Mensaje de peticion "+str(m)
                sender=m.getSender()
                d=eval(m.getContent())
                desc=None
                if d.has_key("desc"): desc=d["desc"]
                ID=m.getConversationId()
                if "Entry"==d["main"]:
                    allow=self.organization.entryUnitTest(sender.getName(),desc)
                    if allow:
                        self.organization.addMember(sender.getName())
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Allowed:"+self.organization.password)
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                    else:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Not-Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                elif "DataForm"==d["main"]:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent(str(self.organization.dataForm))
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)

    class PresenceBehaviour(Behaviour.Behaviour):
        def __init__(self,muc_name,roomname,nick,unit):
            Behaviour.Behaviour.__init__(self)
            self.muc_name=muc_name
            self.name=roomname
            self.nick=nick
            self.unit=unit


        def _process(self):
            msg = self._receive(True)
            if msg:
                if msg.getType()=="unavailable":
                    if msg.getRole()=="none" and msg.getFrom()==self.name+"@"+self.muc_name+"/"+self.nick:
                        x=msg.getTag("x")
                        if x:
                            self.unit.state="unavailable"
                            destroy=x.getTag("destroy")
                            if destroy:
                                print "The room "+self.name+" has been destroyed"
                                if self.unit.owner:
                                    #eliminar del df
                                      time.sleep(random.randint(1,10))
                                      dad = DF.DfAgentDescription()
                                      dad.setAID(self.myAgent.getAID())
                                      search = self.myAgent.searchService(dad)
                                      if search:
                                          newdad=DF.DfAgentDescription()
                                          newdad.setAID(self.myAgent.getAID())
                                          for d in search[0].getServices():
                                              if d.getName()!=self.name and d.getType()!="ORGANIZATION" and d.getType()!="UNIT":
                                                  newdad.addService(d)
                                          self.myAgent.deregisterService(dad)
                                          self.myAgent.registerService(newdad)
                        if msg.getStatusCode()=="301":
                                print "You have been baned"
                        if msg.getStatusCode()=="307":
                                print "You have been kicked"
                        #elimnamos las salas que tenemos dentro
                        units=[]
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        name=self.unit.name
                        if search:
                              for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent" and name in p["value"].strip("u'"):
                                              units.append(str(d.getName()))
                        #units contiene la lista con las unidades descendientes que pertenecen al agente expulsado
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        if search:
                            for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent":
                                              for u in units:
                                                  if u in  p["value"].strip("u'") and d.getName() not in units:
                                                      units.append(str(d.getName()))
                        for u in units:
                              iq = Iq(to=u+"@"+self.muc_name,typ='set')
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
                              item= Node(tag="destroy")
                              query.addChild(node=item)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                        if self.unit.requestBehaviour:
                                      self.myAgent.removeBehaviour(self.unit.requestBehaviour)
                        if self.name in self.myAgent.rooms:
                            self.myAgent.rooms.remove(self.name)
                        self.myAgent.removeBehaviour(self.unit)
                        self.myAgent.removeBehaviour(self)
                        #raise Unavailable
                    else:
                            jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                            if jid in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.remove(jid)
                else:
                        jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                        if jid not in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.append(jid)
                                  if self.unit.owner:
                                      self.unit.addAdmin(jid)






class Team(Unit):
    def __init__(self,agent, nick, name=None,password=None, goalList=[], agentList=[],contentLanguage="sl",create=True):
        self.leader=False
        Unit.__init__(self,agent, nick, name, "Team", goalList, agentList, contentLanguage,password,create)


    def myCreate(self):
          if not self.checkGoal(self.goalList):
              return NotValidGoal
          elif not self.checkType():
              return NotValidType
          elif not self.testRoomName():
              return NotValidName
          elif not self.createRoom():
              return CreationError
          else:
              self.state="available"
              if self.agentList!=[]:
            #enviando invitaciones
                for a in self.agentList:
                  self.addMember(a)

              dad = DF.DfAgentDescription()
              dad.setAID(self.myAgent.getAID())
              search = self.myAgent.searchService(dad)
              if search:
                  dad=search[0]
                  d = DF.DfAgentDescription()
                  d.setAID(self.myAgent.getAID())
                  self.myAgent.deregisterService(d)
              else:
                  dad = DF.DfAgentDescription()
                  dad.setAID(self.myAgent.getAID())
              ds = DF.ServiceDescription()
              ds.setType("UNIT")
              ds.setName(self.name)
              ds.addProperty({"name":"parent","value":self.parent})
              dad.addService(ds)
              res = self.myAgent.registerService(dad)
              cont=0
              while not res and cont<3:
                 res = self.myAgent.registerService(dad)
                 cont=cont+1
              if not res: return CreationError
              self.owner=True
              self.leader=True
              template = Behaviour.ACLTemplate()
              template.setProperty("from",self.name)
              t = Behaviour.MessageTemplate(template)
              self.setTemplate(t)
              p = Presence(frm=self.muc_name)
              t = Behaviour.MessageTemplate(p)
              self.presenceBehaviour=self.PresenceBehaviour(self.muc_name,self.name,self.nick,self)
              self.myAgent.addBehaviour(self.presenceBehaviour, t)
          #aÃ±adiendo el comportamiento de respuesta a las solicitudes
              template = Behaviour.ACLTemplate()
              template.setProperty("from",self.name)
              template.setPerformative("request")
              template.setOntology("spade:x:unit")
              t = Behaviour.MessageTemplate(template)
              self.requestBehaviour=self.RequestBehaviour(self)
              self.myAgent.addBehaviour(self.requestBehaviour, t)
              p = Presence()
              t = Behaviour.MessageTemplate(p)
              self.presenceBehaviour=self.PresenceBehaviour(self.muc_name,self.name,self.nick,self)
              self.myAgent.addBehaviour(self.presenceBehaviour, t)
              self.dataForm=[]
              return True


    def myJoin(self):
        result=Unit.myJoin(self)
        template = Behaviour.ACLTemplate()
        template.setProperty("from",self.name)
        template.setPerformative("request")
        t = Behaviour.MessageTemplate(template)
        self.requestBehaviour=self.RequestBehaviour(self)
        return result


    def requestLeadership(self,desc=None):
      if self.state=="unavailable":
          raise Unavailable
          return
      #consultar en el DF quien es el owner de la organizaciÃ³n
      moderator=[]
      dad = DF.DfAgentDescription()
      ds = DF.ServiceDescription()
      ds.setType("UNIT")
      ds.setName(self.name)
      dad.addService(ds)
      search = self.myAgent.searchService(dad)
      if search:
          owner=search[0].getAID()
          #comportammiento con mensaje ACL solicitando permiso
          ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
          template = Behaviour.ACLTemplate()
          template.setSender(owner)
          template.setPerformative("inform")
          template.setOntology("spade:x:unit")
          template.setProperty("from",self.name)
          template.setConversationId(ID)
          t = Behaviour.MessageTemplate(template)
          b=self.RequestLeaderBehaviour(owner,self.name,desc,ID)
          self.myAgent.addBehaviour(b, t)
          b.join()
          return b.result

    class RequestLeaderBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,owner,roomname,desc,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.owner=owner
            self.name=roomname
            self.desc=desc
            self.ID=ID
            self.result=False

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="Leader"
            if self.desc:
                desc["desc"]=self.desc
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            msg.addReceiver(self.owner)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                if "Allowed"==ans.getContent():
                   self.leader=True
                   self.result=True



    def requestExpulsion(self,jid,desc=None):
      if self.state=="unavailable":
          raise Unavailable
          return
      #consultar en el DF quien es el owner de la organizaciÃ³n
      moderator=self.getModeratorList()
      #comportammiento con mensaje ACL solicitando permiso
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      template = Behaviour.ACLTemplate()
      template.setPerformative("inform")
      template.setOntology("spade:x:unit")
      template.setProperty("from",self.name)
      template.setConversationId(ID)
      t = Behaviour.MessageTemplate(template)
      b=self.RequestKickBehaviour(moderator,self.name,jid,desc,ID)
      self.myAgent.addBehaviour(b, t)
      b.join()
      return b.result

    class RequestKickBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,moderator,roomname,jid,desc,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.moderator=moderator
            self.name=roomname
            self.jid=jid
            self.desc=desc
            self.ID=ID
            self.result=False

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="Kick"
            desc["jid"]=self.jid
            if self.desc:
                desc["desc"]=self.desc
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            for m in self.moderator:
                aid=AID.aid(m,["xmpp://"+m])
                msg.addReceiver(aid)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                if "Agree"==ans.getContent():
                   self.result=True

    def requestPermanentExpulsion(self,jid,desc=None):
      if self.state=="unavailable":
          raise Unavailable
          return
      #consultar en el DF quien es el owner de la organizaciÃ³n
      moderator=self.getModeratorList()
      #comportammiento con mensaje ACL solicitando permiso
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      template = Behaviour.ACLTemplate()
      template.setPerformative("inform")
      template.setOntology("spade:x:unit")
      template.setProperty("from",self.name)
      template.setConversationId(ID)
      t = Behaviour.MessageTemplate(template)
      b=self.RequestBanBehaviour(moderator,self.name,jid,desc,ID)
      self.myAgent.addBehaviour(b, t)
      b.join()
      return b.result

    class RequestBanBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,moderator,roomname,jid,desc,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.moderator=moderator
            self.name=roomname
            self.jid=jid
            self.desc=desc
            self.ID=ID
            self.result=False

        def _process(self):
            msg=ACLMessage.ACLMessage()
            desc={}
            desc["main"]="Ban"
            desc["jid"]=self.jid
            if self.desc:
                desc["desc"]=self.desc
            msg.setContent(str(desc))
            msg.setPerformative("request")
            msg.setOntology("spade:x:unit")
            if (msg.getSender() == None):
                msg.setSender(self.myAgent.getAID())
            for m in self.moderator:
                aid=AID.aid(m,["xmpp://"+m])
                msg.addReceiver(aid)
            msg.setProperty("from",self.name)
            msg.setConversationId(self.ID)
            self.myAgent.send(msg)
            ans= self._receive(True,30)
            if ans:
                if "Agree"==ans.getContent():
                   self.result=True

    class RequestBehaviour(Behaviour.Behaviour):
        def __init__(self,organization):
            Behaviour.Behaviour.__init__(self)
            self.organization=organization

        def _process(self):
            m= self._receive(True)
            if m:
                desc=None
                sender=m.getSender()
                d=eval(m.getContent())
                desc=None
                if d.has_key("desc"): desc=d["desc"]
                ID=m.getConversationId()
                if "Leader"==d["main"]:
                    allow=self.organization.leadershipTest(sender.getName(),desc)
                    if allow:
                        self.organization.giveLeadership(sender.getName())
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                    else:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Not-Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                if "Kick"==d["main"]:
                    jid=d["jid"]
                    allow=self.organization.explusionTest(sender.getName(),jid,desc)
                    if allow:
                        self.organization.expulsion(jid)
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Agree")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                if "Ban"==d["main"]:
                    jid=d["jid"]
                    allow=self.organization.permanentExplusionTest(sender.getName(),jid,desc)
                    if allow:
                        self.organization.permanentExplusion(jid)
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Agree")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                if "Entry"==d["main"]:
                    allow=self.organization.entryUnitTest(sender.getName(),desc)
                    if allow:
                        self.organization.addAdmin(sender.getName())
                        msg=ACLMessage.ACLMessage()
                        if self.organization.password=="" or not self.organization.password:
                            msg.setContent("Allowed")
                        else:
                            msg.setContent("Allowed:"+self.organization.password)
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                    else:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent("Not-Allowed")
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)
                if "DataForm"==d["main"]:
                        msg=ACLMessage.ACLMessage()
                        msg.setContent(str(self.organization.dataForm))
                        msg.setPerformative("inform")
                        msg.setOntology("spade:x:unit")
                        msg.setProperty("from",self.organization.name)
                        msg.setConversationId(ID)
                        if (msg.getSender() == None):
                            msg.setSender(self.myAgent.getAID())
                        msg.addReceiver(sender)
                        self.myAgent.send(msg)



    def leaderTest(self,sender,desc):
        "Metodo que permite definir cuando se permite que un miembro del equipo sea lider"
        return False
    def entryUnitTest(self,sender,desc):
        return False
    def permanentExplusionTest(self,sender,jid,desc):
        return False

    def expulsionTest(self,sender,jid,desc):
        return False

    def getMaxAgents(self):
      """
      Returns Maximum agents allowed to enter inside the Organization
      """
      if self.state=="unavailable":
        raise Unavailable
        return
      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
      p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
      t1 = Behaviour.MessageTemplate(p)
      b=self.GetMaxAgentsBehaviour(self.muc_name,self.name,ID)
      self.myAgent.addBehaviour(b, t1)
      b.join()
      return b.result

    class GetMaxAgentsBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=None

        def _process(self):

              maxAgents=None
              iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
              query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
              iq.addChild(node=query)
              self.myAgent.jabber.send(iq)
              msg = self._receive(True,10)
              if msg:
                  query = msg.getTag("query")
                  if query:
                    x = query.getTag("x")
                    items =x.getChildren()
                    for item in items:
                     if item.getAttr("var")=="muc#roominfo_maxusers":
                      maxAgents=item.getTags("value")[0].getData()
              if maxAgents==None:
                  print "Maximum agents has not been established"
              self.result=maxAgents
    def getMinAgents(self):
        """
        Returns Minimum agents needed to allow conversations inside
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t1 = Behaviour.MessageTemplate(p)
        b=self.GetMinAgentsBehaviour(self.muc_name,self.name,ID)
        self.myAgent.addBehaviour(b, t1)
        b.join()
        return b.result

    class GetMinAgentsBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.result=None

        def _process(self):
            minAgents=None
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg:
              query = msg.getTag("query")
              if query:
                x = query.getTag("x")
                items =x.getChildren()
                for item in items:
                      if item.getAttr("var")=="muc#roominfo_minusers":
                           minAgents=item.getTags("value")[0].getData()
              if minAgents==None:
                  print "Minimum agents has not been established"
            self.result= minAgents

    def setMaxAgents(self,maxUsers):
        """
         Updates Maximum agents allowed to enter inside the Organization
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t1 = Behaviour.MessageTemplate(p)
        b=self.SetMaxAgentsBehaviour(self.muc_name,self.name,ID,maxUsers)
        self.myAgent.addBehaviour(b, t1)
        b.join()

    class SetMaxAgentsBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,maxUsers):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.maxUsers=maxUsers

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg.getAttr("type")!="result":
                 print "Forbidden. Not owner" #completar un poco el error
                 return
              #setting room configuration
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
            x=Node(tag="x", attrs={"xmlns":"jabber:x:data"," type":"submit"})
            resquery=msg.getQueryChildren()[0] #nos quedamos con el hijo de query
            if resquery: items = resquery.getTags("field")
            if resquery==None:
                print "No configuration is possible"
                self.result= False
            for item in items:
                value=None
                if item.getAttr("var"):
                    value=item.getAttr("value") #tomamos el valor
                if item.getAttr("var") == "muc#roomconfig_maxusers":
                    value=self.maxUsers
                if value:
                    node=Node(tag="field", attrs={"var":item.getAttr("var")})
                    valnode=Node(tag="value")
                    valnode.addData(value)
                    node.addChild(node=valnode)
                    x.addChild(node=node)
            query.addChild(node=x)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)


    def setMinAgents(self,minUsers):
        """
        Updates Minimum agents needed to allow conversations inside
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
        t1 = Behaviour.MessageTemplate(p)
        b=self.SetMinAgentsBehaviour(self.muc_name,self.name,ID,minUsers)
        self.myAgent.addBehaviour(b, t1)
        b.join()
        p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID+"a"})
        t1 = Behaviour.MessageTemplate(p)
        b=self.MinAgentsBehaviour(self.muc_name,self.name,ID+"a",self)
        self.myAgent.addBehaviour(b, t1)

    class SetMinAgentsBehaviour(Behaviour.OneShotBehaviour):
        def __init__(self,muc_name,roomname,ID,minUsers):
            Behaviour.OneShotBehaviour.__init__(self)
            self.ID=ID
            self.muc_name=muc_name
            self.name=roomname
            self.minUsers=minUsers

        def _process(self):
            iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)
            msg = self._receive(True,10)
            if msg.getAttr("type")!="result":
                 print "Forbidden. Not owner"
                 return
              #setting room configuration
            iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
            query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
            x=Node(tag="x", attrs={"xmlns":"jabber:x:data"," type":"submit"})
            resquery=msg.getQueryChildren()[0] #nos quedamos con el hijo de query
            if resquery: items = resquery.getTags("field")
            if resquery==None:
                print "No configuration is possible"
                self.result= False
            for item in items:
                value=None
                if item.getAttr("var"):
                    value=item.getAttr("value") #tomamos el valor
                if item.getAttr("var") == "muc#roomconfig_minusers":
                    value=self.minUsers
                if value:
                    node=Node(tag="field", attrs={"var":item.getAttr("var")})
                    valnode=Node(tag="value")
                    valnode.addData(value)
                    node.addChild(node=valnode)
                    x.addChild(node=node)
            query.addChild(node=x)
            iq.addChild(node=query)
            self.myAgent.jabber.send(iq)



    def expulsion(self,Agentjid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if self.myAgent.JID not in self.getModeratorList() and not self.owner:
            raise NotAllowed
            return
        Unit.kickAgent(self,Agentjid)

    def getPermanentExpulsionList(self,Agentjid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if self.myAgent.JID not in self.getModeratorList() and not self.owner:
            raise NotAllowed
            return
        return Unit.getBanAgentList()

    def permanentExpulsion(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if self.myAgent.JID not in self.getModeratorList() and not self.owner:
            raise NotAllowed
            return
        Unit.addBanAgent(self,jid)

    def revokePermanentExplusion(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if self.myAgent.JID not in self.getModeratorList() or self.owner:
            raise NotAllowed
            return
        Unit.removeBanAgent(self,jid)

    def getMemberList(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        admins=Unit.getAdminList(self)
        owner=Unit.getOwnerList(self)
        moderator=Unit.getModeratorList(self)
        for o in owner:
            if o in moderator:
                admins.append(o)
        return admins

    def getNumberOfAgents(self):
        if self.state=="unavailable":
            raise Unavailable
            return
        return Unit.getNumberOfAgents(self)

    def setGoal(self,goalList):
        """
        Updates organization goals
        """
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        Unit.setGoal(self,goalList)




    def checkCreationPermission(self):
            return True

    def giveLeadership(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        self.addOwner(jid)
        self.addModerator(jid)

    def revokeLeadership(self,jid):
        if self.state=="unavailable":
            raise Unavailable
            return
        if not self.owner:
            raise NotAllowed
            return
        print "revoking to "+jid
        self.addAdmin(jid)
        self.removeModerator(jid)

    def addMember(self,agent):
        self.invite([agent])
        self.addAdmin(agent)
        self.removeModerator(agent)



    class PresenceBehaviour(Behaviour.Behaviour):
        def __init__(self,muc_name,roomname,nick,unit):
            Behaviour.Behaviour.__init__(self)
            self.muc_name=muc_name
            self.name=roomname
            self.nick=nick
            self.unit=unit


        def _process(self):
            msg = self._receive(True)
            if msg:
                if msg.getType()=="unavailable":
                    if msg.getRole()=="none" and msg.getFrom()==self.name+"@"+self.muc_name+"/"+self.nick:
                        x=msg.getTag("x")
                        if x:
                            self.unit.state="unavailable"
                            destroy=x.getTag("destroy")
                            if destroy:
                                print "The room "+self.name+" has been destroyed"
                                if self.unit.owner:
                                    #eliminar del df
                                      time.sleep(random.randint(1,10))
                                      dad = DF.DfAgentDescription()
                                      dad.setAID(self.myAgent.getAID())
                                      search = self.myAgent.searchService(dad)
                                      if search:
                                          newdad=DF.DfAgentDescription()
                                          newdad.setAID(self.myAgent.getAID())
                                          for d in search[0].getServices():
                                              if d.getName()!=self.name and d.getType()!="ORGANIZATION" and d.getType()!="UNIT":
                                                  newdad.addService(d)
                                          self.myAgent.deregisterService(dad)
                                          self.myAgent.registerService(newdad)
                        if msg.getStatusCode()=="301":
                                print "You have been baned"
                        if msg.getStatusCode()=="307":
                                print "You have been kicked"
                        #elimnamos las salas que tenemos dentro
                        units=[]
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        name=self.unit.name
                        if search:
                              for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent" and name in p["value"].strip("u'"):
                                              units.append(str(d.getName()))
                                          if "Team:" in self.unit.name and (self.unit.parent_type=="Federation" or self.unit.parent_type=="Matrix"):
                                              #si te han explusado del equipo de supervisores añadimos tus salas propias
                                              if p["name"].strip("u'")=="parent" and self.unit.parent== p["value"].strip("u'"):
                                                  units.append(str(d.getName()))

                        #units contiene la lista con las unidades descendientes que pertenecen al agente expulsado
                        dad = DF.DfAgentDescription()
                        dad.setAID(self.myAgent.getAID())
                        ds = DF.ServiceDescription()
                        ds.setType("UNIT")
                        dad.addService(ds)
                        search = self.myAgent.searchService(dad)
                        if search:
                            for s in search:
                                  for d in s.getServices():
                                      prop=d.getProperties()
                                      for p in prop:
                                          if p["name"].strip("u'")=="parent":
                                              for u in units:
                                                  if u in p["value"].strip("u'") and str(d.getName()) not in units:
                                                      units.append(str(d.getName()))
                        for u in units:
                              iq = Iq(to=u+"@"+self.muc_name,typ='set')
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#owner")
                              item= Node(tag="destroy")
                              query.addChild(node=item)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                        if self.unit.requestBehaviour:
                                      self.myAgent.removeBehaviour(self.unit.requestBehaviour)
                        if self.name in self.myAgent.rooms:
                            self.myAgent.rooms.remove(self.name)
                        self.myAgent.removeBehaviour(self.unit)
                        self.myAgent.removeBehaviour(self)
                        #raise Unavailable
                    else:
                            jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                            if jid and jid in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.remove(jid)
                                  if self.unit.owner and jid != self.myAgent.JID:
                                      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
                                      p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
                                      t1 = Behaviour.MessageTemplate(p)
                                      b=self.unit.MinAgentsBehaviour(self.muc_name,self.name,ID,self.unit)
                                      self.myAgent.addBehaviour(b, t1)
                else:
                        jid=str(msg.getTag("x").getTag("item").getAttr("jid")).split("/")[0]
                        if jid and jid not in self.unit.members and str(msg.getFrom()).count("@")==1  and self.name+"@"+self.muc_name in str(msg.getFrom()):
                                  self.unit.members.append(jid)
                                  if self.unit.owner and jid != self.myAgent.JID:
                                      self.unit.addAdmin(jid)
                                      self.unit.removeModerator(jid)
                                      ID="".join([string.ascii_letters[int(random.randint(0,len(string.ascii_letters)-1))] for a in range(5)])
                                      p = Iq(frm=self.name+"@"+self.muc_name, attrs={"id":ID})
                                      t1 = Behaviour.MessageTemplate(p)
                                      b=self.unit.MinAgentsBehaviour(self.muc_name,self.name,ID,self.unit)
                                      self.myAgent.addBehaviour(b, t1)

    class MinAgentsBehaviour(Behaviour.OneShotBehaviour):
            def __init__(self,muc_name,roomname,ID,unit):
                Behaviour.OneShotBehaviour.__init__(self)
                self.ID=ID
                self.muc_name=muc_name
                self.name=roomname
                self.result=[]
                self.unit=unit

            def _process(self):
                minAgents="0"
                iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
                iq.addChild(node=query)
                self.myAgent.jabber.send(iq)
                msg = self._receive(True,10)
                if msg:
                  query = msg.getTag("query")
                  if query:
                    x = query.getTag("x")
                    if x:
                        items =x.getChildren()
                        for item in items:
                              if item.getAttr("var")=="muc#roominfo_minusers":
                                   minAgents=item.getTags("value")[0].getData()
                  agents="0"
                  iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                  query = Protocol('query',xmlns="http://jabber.org/protocol/disco#info")
                  iq.addChild(node=query)
                  self.myAgent.jabber.send(iq)
                  msg = self._receive(True,10)
                  if msg:
                    query = msg.getTag("query")
                  if query:
                    x = query.getTag("x")
                    if x:
                        items =x.getChildren()
                        for item in items:
                          if item.getAttr("var")=="muc#roominfo_occupants":
                            agents=item.getTags("value")[0].getData()
                  if agents and minAgents and int(agents)<int(minAgents):
                      iq = Iq(to=self.name+"@"+self.muc_name,typ='get', attrs={"id":self.ID})
                      query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                      item= Node(tag="item", attrs={"role":"participant"})
                      query.addChild(node=item)
                      iq.addChild(node=query)
                      self.myAgent.jabber.send(iq)
                      msg=self._receive(True,10)
                      if msg:
                          error=msg.getError()
                          if error!=None:
                            print error
                            return
                          q = msg.getTag("query")
                          if q:
                              iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                              query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                              for item in self.unit.members:
                                  i= Node(tag="item", attrs={"jid":item,"role":"visitor"})
                                  query.addChild(node=i)
                              iq.addChild(node=query)
                              self.myAgent.jabber.send(iq)
                              self.unit.state="locked"
                if agents and minAgents and int(agents)>=int(minAgents) and self.unit.state=="locked":
                          iq = Iq(to=self.name+"@"+self.muc_name,typ='set', attrs={"id":self.ID})
                          query = Protocol('query',xmlns="http://jabber.org/protocol/muc#admin")
                          for item in self.unit.members:
                              i= Node(tag="item", attrs={"jid":item,"role":"participant"})
                              query.addChild(node=i)
                          iq.addChild(node=query)
                          self.myAgent.jabber.send(iq)
                          self.unit.state="available"











